package logica;
import java.util.*;
/**
**********************************************************************************************<br/>
* Grafo es un arreglo de estructuras de tipo Vertice. Aqui la estructura nodo esta conformada por dos campos.<br/>
* El primero es el campo indice que es el identificador de un nodo. <br/>
* El segundo es el campo siguiente que es un apuntador a otra estructura de tipo Vertice.usando Asocioacion
* El Algoritmo  de lectura<br/><br/>
//Obtengo la matriz desde el lector de archivos con todas las lineas <br/>
//Estas lineas en realidad son arreglos de tipo entero con las incidencias <br/>
//&nbsp; <b>Nota:</b> Se leyo el archivo se crearon arreglos de entero asi que tambien estan los costos y los objetivos en la matriz<br/>
<br/>
* por cada a en [Aristas] hacer<br/> 
* &nbsp;&nbsp;&nbsp;&nbsp;por cada v en [Vertices] hacer<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;si [a<sub>i</sub> == 1 y existe relacion==<code>false</code>]entonces<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cree un nuevo verticeA;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;existe relacion <code>true</code><br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;si no entoces<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;si[a<sub>i</sub> == 1 y existe relacion==<code>true</code>] entonces<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cree un nuevo verticeB;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cree relacion [verticeA,verticeB,costo];<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fin si<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fin si<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;fin por cada<br/>
* fin por cada<br/>
* @author Jefferson Amado Pe&ntilde;a Torres
**********************************************************************************************
* @see Grafo
* @see LectorDeArchivos
* @version 1.00 2010/11/10
*/
public class EnrutamientoMulticast {
	private Vector<int[]> matriz;
	private int[] vObjetivos,vCostos;
	/**
	*Grafo
	*/
 	public Grafo grafo; 
	/**
	*numero de vertice,numero de aristas y numero de objetivos
	*/
	public int nVertices,nAristas,nObjetivos;
	/**
	*Contructor de la clase EnrutamientoMulticast
	*/
	public EnrutamientoMulticast(){	}
	/**
	*Contructor de la clase EnrutamientoMulticast
	*@param matriz asigna una matriz para ser convertida a grafo
	*/
	public EnrutamientoMulticast(Vector<int[]> matriz){
		this.matriz=matriz;
		computeEnrutamientoMulticast();
	}
        /**
	*Retorna la matriz EnrutamientoMulticast
	*@return matriz asigna una matriz para ser convertida a grafo
	*/
	public Object[] getMatriz(){
            return this.matriz.toArray();
	}
	/**
	*Establece la matriz EnrutamientoMulticast
	*@param matriz asigna una matriz para ser convertida a grafo
	*/
	public void setMatriz(Vector<int[]> matriz){
		//System.out.println("En setMatriz(Vector<int[]> matriz)");
		this.matriz=matriz;
		computeEnrutamientoMulticast();
	}
	/**
	*Obtiene los costos que poseen las aristas o asociaciones
	*@return arreglo de enteros
	*/
	public int[] getCostos(){
		return vCostos;
	}
	/**
	*Obtiene los objetivos 
	*@return arreglo de enteros
	*/
	public int[] getObjetivos(){
	 return vObjetivos;
	}
	/**
	*Retorna el grafo 
	*@return grafo a ser procesado
	*/	
	public Grafo getGrafo(){
		//System.out.println(grafo);
		return grafo;
	}
        /**
         * 
         */
        public Grafo toGrafo(int [][] entrada){
            int verticeA=-1;
            int incidencia=-1;
            Grafo GrafoDEntrada=new Grafo();
            //System.out.print(entrada.length+" , "+entrada[0].length);
            //----------------------------------------
            //Creo los vertices del grafo
            for(int nombreVertice=1;nombreVertice<entrada.length+1;nombreVertice++){
                GrafoDEntrada.ingresarNodo(nombreVertice+"");
            }
            ManejadorDeArchivo.printMatrix(entrada);
	    for(int b=0;b<entrada[0].length;b++){
			for(int a=0;a<entrada.length;a++){
				int [] linea=entrada[a];
				if(linea[b]==1&& incidencia!=b){//donde
					verticeA=a;
					incidencia=b;
				}else if(linea[b]==1 && incidencia==b){
                                        //System.out.print("va: "+(verticeA+1)+" >> "+(a+1)+" \n");
                			GrafoDEntrada.adicionarEnlace((verticeA+1)+"",(a+1)+"",vCostos[b]);
				}
			}
			incidencia=-1; // limpio el verificador para la siguiente columnas
		}
            return GrafoDEntrada;
        }
	/**
	*Despues de leeido el archivo, creada la matriz este metodo crea los vertice , los asocia,<br/>
	*asigna el numero de vertices,el numero de aristas,la cantidad de objetivos
	*/
	public void computeEnrutamientoMulticast(){
		//System.out.println("En computeEnrutamientoMulticast()");
		
		int[] linea=matriz.get(0);//linea 0 con nVertices - nAristas -nObjetivos
		nVertices=linea[0];nAristas=linea[1];nObjetivos=linea[2];
		//System.out.println(">> "+nVertices+" "+nAristas+" "+nObjetivos+" <<");
		vCostos=matriz.get(nVertices+1); //Costos
		vObjetivos=matriz.get(nVertices+2); //Objetivo
		int verticeA=-1;
		grafo=new Grafo();
		//System.out.println(">>> "+grafo);
		//----------------------------------------
		//Creo los vertices del grafo
		for(int nombreVertice=1;nombreVertice<nVertices+1;nombreVertice++){
			grafo.ingresarNodo(nombreVertice+"");
		}
		//----------------------------------------
		//Las siguientes V lineas especican la matriz de incidencia del grafo original
		int incidencia=-1; //veriica que en la columna ya halla seleccionado un vertice de partida
		for(int b=0;b<nAristas;b++){
			for(int a=1;a<nVertices+1;a++){
				linea=matriz.get(a);
				if(linea[b]==1 && incidencia != b){//donde
					verticeA=a;
					incidencia=b;
				}else if(linea[b]==1 && incidencia==b){
                			grafo.adicionarEnlace(verticeA+"",a+"",new Double(vCostos[b]).doubleValue());
				}
			}
			incidencia=-1; // limpio el verificador para la siguiente columnas
		}
		for(int i=0;i<vObjetivos.length;i++){
			grafo.ingresarVerticeObjetivo(vObjetivos[i]+"");
		}
	}

}
